package com.ant.storage.controller;

import com.alibaba.fastjson.JSONObject;
import com.ant.storage.common.ResultCode;
import com.ant.storage.common.ResultVo;
import com.ant.storage.handler.AntException;
import com.ant.storage.pojo.InvoiceInfo;
import com.ant.storage.pojo.PurchaserRecord;
import com.ant.storage.pojo.PurchaserRecordImg;
import com.ant.storage.service.IInvoiceInfoService;
import com.ant.storage.service.IPurchaserRecordImgService;
import com.ant.storage.service.IPurchaserRecordService;
import com.ant.storage.utils.ImageUtil;
import com.ant.storage.wechat.WeChatUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.ObjectUtils;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;

;

/**
 * 文件上传
 *
 * @authormelon
 * @since2021/4/27
 */
@RestController()
@RequestMapping("/uploadFile")
@Api(tags = "上传文件接口")
@CrossOrigin
public class FileController {

    @Autowired
    private IPurchaserRecordImgService recordImgService;

    @Autowired
    private IInvoiceInfoService infoService;


    @Autowired
    private IPurchaserRecordService  recordService;

    @Value("${file.upload-path}")
    private String uploadPath;

    @Value("${fileUrl.url}")
    private String fileUrl;

    @ApiOperation(value = "上传图片")
    @PostMapping("/singleUpload")
    public ResultVo fileUpload(@RequestParam("file") MultipartFile file) throws Exception {
        try {
            if (file.isEmpty()) {
                return ResultVo.success("请选择文件");
            }
            Map<String, String> str = savaFile(file,"Y");
            if (str.size()>0) {
                String ids = savaImage(fileUrl + "/" + str.get("file_name"),str.get("media_id"));
                Map<String,Object> map=new HashMap<>();
                map.put("id",ids);
                map.put("url",fileUrl + "/" + str.get("file_name"));
                map.put("media_id",str.get("media_id"));
                return ResultVo.success("上传成功", map);
            } else {
                return ResultVo.fail("上传失败");
            }
        }catch (Exception e){
            throw  new AntException(ResultCode.NOT_FOUND);
        }

    }


    @ApiOperation(value = "上传图片")
    @PostMapping("/singleUploads")
    public ResultVo fileUploads(@RequestParam("file") MultipartFile file) throws Exception {
        try {
            if (file.isEmpty()) {
                return ResultVo.success("请选择文件");
            }
            Map<String, String> str = savaFile(file,"N");
            if (str.size()>0) {
                String ids = savaImage(fileUrl + "/" + str.get("file_name"),null);
                Map<String,Object> map=new HashMap<>();
                map.put("id",ids);
                map.put("url",fileUrl + "/" + str.get("file_name"));
                return ResultVo.success("上传成功", map);
            } else {
                return ResultVo.fail("上传失败");
            }
        }catch (Exception e){
            throw  new AntException(ResultCode.NOT_FOUND);
        }

    }



    @ApiOperation(value = "上传文件")
    @PostMapping("/singleUploadFile")
    public ResultVo singleUploadFile(@RequestParam("file") MultipartFile file) throws Exception {
        try {
            if (file.isEmpty()) {
                return ResultVo.success("请选择文件");
            }
            Map<String, String> str = savaFile(file,"N");
            if (str.size()>0) {
               String ids = savaImage(fileUrl + "/" + str.get("file_name"),str.get("media_id"));
               // String ids = savaImage(fileUrl + "/" + str.get("file_name"),"11111");
                Map<String,Object> map=new HashMap<>();
                map.put("id",ids);
                map.put("url",fileUrl + "/" + str.get("file_name"));
                map.put("media_id",str.get("media_id"));
                return ResultVo.success("上传成功", map);
            } else {
                return ResultVo.fail("上传失败");
            }
        }catch (Exception e){
            throw  new AntException(ResultCode.NOT_FOUND);
        }

    }


    /**
     * 单个文件上传
     *
     * @param multipartFile
     * @return
     * @throws IOException
     */
    public Map<String,String> savaFile(MultipartFile multipartFile,String code) throws IOException {
        Map<String,String> map=new HashMap<>();
        try {
            // 上传目录地址
            String uploadDir = uploadPath;
            // 如果目录不存在，自动创建文件夹
            File dir = new File(uploadDir);
            if (!dir.exists()) {
                dir.mkdir();
            }
            // 文件尺寸
            //long size = multipartFile.getSize();
            // 文件类型
           // String type = multipartFile.getContentType();
            //获取上传文件的后缀名
            String suffixName = multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().indexOf("."));
            // 获取上传文件的名称
            String uuid = UUID.randomUUID().toString().replace("-", "");
            String filename = uuid + suffixName;
            File newFile = new File(uploadDir + filename);
            // 完成文件上传
            try {
                multipartFile.transferTo(newFile);
                if("Y".equals(code)){
                    String str;
                    if((".xls").equals(suffixName) || (".xlsx").equals(suffixName) || (".pdf").equals(suffixName)){
                        str = WeChatUtils.upload("file", null, newFile);
                    }else {
                        str = WeChatUtils.upload("image", null, newFile);
                    }
                    if(str!=null){
                        JSONObject jsonObject = JSONObject.parseObject(str);
                        String errcode = jsonObject.getString("errcode");
                        if (StringUtils.isNotEmpty(errcode) && errcode.equals("0")) {
                            String media_id = jsonObject.getString("media_id");
                            map.put("media_id",media_id);
                            map.put("file_name",filename);
                        }else{
                            map.put("media_id",null);
                            map.put("file_name",filename);
                        }
                    }
                }else{
                    map.put("file_name",filename);
                }
                return map;
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 保存图片
     *
     * @param url
     * @return
     */
    public String savaImage(String url,String media_id) {
        PurchaserRecordImg img = new PurchaserRecordImg();
        img.setUrl(url);
        img.setMediaId(media_id);
        recordImgService.save(img);
        return img.getId().toString();
    }

    /**
     * 压缩上传图片
     */
    @ApiOperation(value = "压缩上传图片")
    @PostMapping("/compressUpload")
    public String compressUpload(@RequestParam("file") MultipartFile multipartFile) throws IOException {

        // 上传目录地址
        String uploadDir = uploadPath;
        // 如果目录不存在，自动创建文件夹
        File dir = new File(uploadDir);
        if (!dir.exists() && !dir.isDirectory()) {
            dir.mkdir();
        }
        //获取上传文件的后缀名
        String suffixName = multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().indexOf("."));
        // 获取上传文件的名称
        String uuid = UUID.randomUUID().toString().replace("-", "");
        String filename = uuid + suffixName;
        File newFile = new File(uploadDir + filename);
        // 完成文件上传
        try {
            // 先尝试压缩并保存图片
            Thumbnails.of(multipartFile.getInputStream()).scale(0.5f)
                    .outputQuality(0.15f)
                    .outputFormat("jpg")
                    .toFile(newFile);
            return newFile.getName();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

    }

    /**
     * 上传多个文件
     */
    @ApiOperation(value = "上传多个文件")
    @PostMapping("/multiUpload")
    public ResultVo multiUpload(@RequestParam("file") MultipartFile[] files) throws IOException {
        if (files.length == 0) {
            return ResultVo.success("请选择文件");
        }
        String str = "";
        for (MultipartFile file : files) {
            str += savaFile(file,"N") + ",";
        }
        if (str != null) {
            String ids = savaImage(fileUrl + "/" + str,null);
            return ResultVo.success("上传成功", ids);
        } else {
            return ResultVo.fail("上传失败");
        }
    }

    @ApiOperation("压缩单个图片上传")
    @PostMapping(value = "/UploadImage")
    public ResultVo UploadImage(@RequestParam(value = "file", required = false) MultipartFile multipartFile) throws Exception {
        if (ObjectUtils.isEmpty(multipartFile) || multipartFile.getSize()<= 0) {
            return ResultVo.fail("请选择上传文件");
        }
        // 构建byte 数据源
        byte[] source = ImageUtil.compressImageCircle(multipartFile.getBytes(),100,0.5);
        String suffixName = multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().indexOf("."));
        String uuid = UUID.randomUUID().toString().replace("-", "");
        String newFileName=uuid+suffixName;
        String file = ImageUtil.getFileByBytes(source, uploadPath, newFileName);
        if(file!=null){
            String str = this.savaImage(fileUrl + "/" + file,null);
            Map<String,Object> map=new HashMap<>();
            map.put("id",str);
            map.put("url",fileUrl + "/" + file);
            return  ResultVo.success("上传成功",map);
        }
        return  ResultVo.fail("上传失败");
    }


    public String deleteImg(Integer id) throws FileNotFoundException {
        PurchaserRecordImg recordImg = recordImgService.getOne(new QueryWrapper<PurchaserRecordImg>().eq("id", id));
        String path= ResourceUtils.getURL("classpath:").getPath()+recordImg.getUrl();
        File file=new File(path,recordImg.getUrl());
        if(file.exists()){
            file.delete();
        }
        recordImgService.removeById(id);
        return "操作成功";
    }

    @ApiOperation(value = "上传图片2")
    @PostMapping("/upload")
    public ResultVo upload(@RequestParam("file") MultipartFile multipartFile) throws IOException {
        // 文件原名称
        String oldName = multipartFile.getOriginalFilename();
        // 文件后缀
        String extension = "." + FilenameUtils.getExtension(multipartFile.getOriginalFilename());
        // 新文件名
        String newName = UUID.randomUUID().toString().replace("-", "").substring(8) + extension;
        // 文件尺寸
        long size = multipartFile.getSize();
        // 文件类型
        String type = multipartFile.getContentType();
        // 获取编译后项目根路径
        String basePath = ResourceUtils.getURL("classpath:").getPath();
        // 按照时间分类
        String timePath = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        // 根路径/static/files/20xx-xx-xx/

        String suffixName = multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().indexOf("."));
        String uuid = UUID.randomUUID().toString().replace("-", "");

        String finalPath = fileUrl+ uuid;
        // 创建文件夹
        File finalFile = new File(finalPath);
        if (!finalFile.exists()) {
            finalFile.mkdirs();
        }
        // 上传文件: 核心代码
        multipartFile.transferTo(new File(finalFile, newName));
        PurchaserRecordImg img = new PurchaserRecordImg();
        img.setUrl(uploadPath + timePath);
        recordImgService.save(img);
       // return img.getId().toString();
        return ResultVo.success("上传成功", img);

    }

    @ApiOperation(value = "通过id删除图片")
    @DeleteMapping("/deleteImg/{id}")
    public ResultVo deleteFiles(@PathVariable("id") Integer id) {
        // 获取文件路径
        PurchaserRecordImg one = recordImgService.getOne(new QueryWrapper<PurchaserRecordImg>().eq("id", id));
        if(one==null){
            throw new AntException(ResultCode.NOT_FOUND.getCode(),"图片不存在");
        }
        List<InvoiceInfo> annex = infoService.list(new QueryWrapper<InvoiceInfo>().in("annex", one.getId()));
        if(annex!=null && annex.size()>0){
            throw new AntException(ResultCode.NOT_FOUND.getCode(),"图片正在使用，不能删除");
        }
        List<PurchaserRecord> recordList =  recordService.list(new QueryWrapper<PurchaserRecord>().in("img_url_id", one.getId()));
        if(recordList!=null && recordList.size()>0){
            throw new AntException(ResultCode.NOT_FOUND.getCode(),"图片正在使用，不能删除");
        }
        String filePath =  uploadPath + one.getUrl().substring(one.getUrl().lastIndexOf("/") + 1);
        File file = new File(filePath);
        // 判断文件是否存在
        if(file.exists()){
            Boolean flag;
            flag = file.delete();
            if (flag) {
                recordImgService.removeById(id);
                return ResultVo.success("删除成功",file.getName());
            } else {
                return ResultVo.fail("删除失败");
            }
        } else {
            return ResultVo.fail("图片不存在");
        }
    }



    @ApiOperation(value = "通过id删除图片")
    @DeleteMapping("/deleteImgs/{id}")
    public ResultVo deleteImgs(@PathVariable("id") Integer id) {
        // 获取文件路径
        PurchaserRecordImg one = recordImgService.getOne(new QueryWrapper<PurchaserRecordImg>().eq("id", id));
        if(one==null){
            throw new AntException(ResultCode.NOT_FOUND.getCode(),"图片不存在");
        }
        String filePath =  uploadPath + one.getUrl().substring(one.getUrl().lastIndexOf("/") + 1);
        File file = new File(filePath);
        // 判断文件是否存在
        if(file.exists()){
            Boolean flag;
            flag = file.delete();
            if (flag) {
                recordImgService.removeById(id);
                return ResultVo.success("删除成功",file.getName());
            } else {
                return ResultVo.fail("删除失败");
            }
        } else {
            return ResultVo.fail("图片不存在");
        }
    }

    /**
     * 下载文件
     */
    @ApiOperation(value = "下载文件")
    @GetMapping("/download")
    public void downloadFile(String path, HttpServletResponse response) throws Exception {
            // 获取文件路径
       // 读到流中
        InputStream inputStream = new FileInputStream("http://192.168.6.223:9999/storageApi/pic/8fa44059391c4c69be594f5e24279588.xls");// 文件的存放路径
        response.reset();
        response.setContentType("application/octet-stream");
        String filename = new File(path).getName();
        response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));
        ServletOutputStream outputStream = response.getOutputStream();
        byte[] b = new byte[1024];
        int len;
        //从输入流中读取一定数量的字节，并将其存储在缓冲区字节数组中，读到末尾返回-1
        while ((len = inputStream.read(b)) > 0) {
            outputStream.write(b, 0, len);
        }
        inputStream.close();

    }

}
